﻿// Copyright richyp 2009
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Richyp.Bodger.UI {
    public class ListEntry {
        public ListEntry(CodexEntry baseEntry, DataGridView view) {
            DataGridViewRow row = new DataGridViewRow();
            this.BaseEntry = baseEntry;
            this.SetRow(row);
            row.Tag = this;
            this.row.Height = BaseEntry.Height + 12;
            //view.Rows.Add(row);            
        }
      
        private CodexEntry baseEntry = null;
        public CodexEntry BaseEntry {
            get {
                return this.baseEntry;
            }
            set {
                this.baseEntry = value;
                this.Create();
            }
        }

        private DataGridViewRow row = null;
        public DataGridViewRow Row {
            get {
                return this.row;
            }
        }

        public string CurrentCategory { get; set; }
        public string AlternateCategory { get; set; }

        public void SetRow(DataGridViewRow row ) {
            row.Cells.Clear();
            row.Cells.Add(new NiceRenderer(""));
            row.Cells.Add(new NiceRenderer(""));
            row.Cells.Add(new NiceRenderer(""));
            this.row = row;
            this.UpdateRow();            
        }

        public void Create() {
            foreach (Unit unit in this.baseEntry.Units) {
                for (int count = 0; count < unit.InitialQuantity; count++) {
                    Unit newEntry = Unit.Copy(unit);
                    this.units.Add(newEntry);
                }
            }
            this.CurrentCategory = this.baseEntry.Category;
            this.AlternateCategory = this.baseEntry.AltCategory;

            RecalculateDistinctUnits();
        }

        public string GetDescription() {
            return GetDescription(false, false);
        }

        public string GetDescription(bool showDefault, bool showFixed)
        {
            string description = "";
            Dictionary<string, Dictionary<string, int>> groups = new Dictionary<string, Dictionary<string, int>>();
            List<string> groupNames = new List<string>();
            foreach (Unit unit in this.units) {
                Dictionary<string, int> counts = null;
                if (groups.ContainsKey(unit.Group)) {
                    counts = groups[unit.Group];                    
                } else {
                    counts = new Dictionary<string, int>();
                    groupNames.Add(unit.Group);
                }
                if (counts.ContainsKey(unit.Name)) {
                    counts[unit.Name]++;
                } else {
                    counts.Add(unit.Name, 1);
                }
                groups[unit.Group] = counts;
            }

            groupNames.Sort();
            foreach (string groupName in groupNames) {
                if (groupName != "none") {
                    description += "[" + groupName + "]\n";
                }
                Dictionary<string, int> units = groups[groupName];
                foreach (string unitName in units.Keys) {
                    int total = 0;
                
                    int count = units[unitName];
                    Dictionary<string, int> extra = new Dictionary<string, int>();
                    foreach (Unit unit in this.units) {
                        if (unit.Name == unitName) {
                            foreach (Equipment eq in unit.Equipped) {
                                bool display = true;
                                
                                foreach (Equipment def in unit.AllWargear) {
                                    if (def.Wargear.Name == eq.Wargear.Name ) {
                                        if ( def.Wargear.AlwaysHide ||(def.Default && !showDefault) || def.Fixed) {
                                            display = false;
                                            break;
                                        }                                        
                                    }
                                }
                                if (display) {
                                    if (extra.ContainsKey(eq.Wargear.Name)) {
                                        extra[eq.Wargear.Name]++;
                                    } else {
                                        extra[eq.Wargear.Name] = 1;
                                    }
                                }
                            }
                            total += unit.GetTotalCost();
                        }
                    }
                    total += this.baseEntry.CostOffset;
                    string additional = "";
                    foreach (string key in extra.Keys) 
                    {
                        if (units[unitName] > 1)
                        {
                            additional += extra[key] + " x ";
                        }
                        additional += key + " | ";
                    }
                    if (additional.Length > 0) {
                        additional = additional.Substring(0,additional.Length - 3);
                        additional = " (" + additional + ")";
                    }
                    description += " " + count + " x " + unitName + additional + ":" + total + " pts,";
                }
                description = description.Substring(0, description.Length - 1);
                if (groupName != "none") {
                    description += ",";
                }
            }
            
            return description;
        }

        public int GetTotalCost()
        {
            int total = 0;

            foreach (Unit unit in this.Units)
            {
                total += unit.GetTotalCost();
            }

            return total;
        }

        public Unit GetUnitByName(string name) {
            foreach (Unit unit in this.units) {
                if (unit.Name.ToUpper() == name.ToUpper()) {
                    return unit;
                }
            }
            return null;
        }

        public void UpdateRow() {
            int unitEntryCost = 0;
            RecalculateDistinctUnits();
            foreach (Unit unit in this.units) {
                unitEntryCost += unit.GetTotalCost();
            }
            unitEntryCost += this.baseEntry.CostOffset;
            this.row.Height = this.baseEntry.Height + 12;
            if (DistinctUnits > 3)
                this.row.Height += 18 * (DistinctUnits - 3);
            ((NiceRenderer)this.row.Cells[0]).SetContent(this.baseEntry.Category);
            ((NiceRenderer)this.row.Cells[1]).SetContent("-" + this.baseEntry.Name + "\n" + this.GetDescription(true, false),this.BaseEntry.SplitOnEntries);
            ((NiceRenderer)this.row.Cells[2]).SetContent("#" +unitEntryCost.ToString());
        }

        public void SetHeight(int height) {
            this.row.Height = height;
            this.row.DataGridView.Refresh();
        }

        public int DistinctUnits { get; set; }

        private void RecalculateDistinctUnits()
        {
            List<string> unitNames = new List<string>();
            foreach (Unit unit in this.Units)
            {
                if (!unitNames.Contains(unit.Name))
                    unitNames.Add(unit.Name);
            }
            DistinctUnits = unitNames.Count;
        }


        private List<Unit> units = new List<Unit>();
        public List<Unit> Units {
            get {
                return this.units;
            }
        }

        public int Height {
            get {
                return this.row.Height;
            }
        }
    }
}
